﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KouDai.Core.Queue
{
    public class AsyncProducerConsumerCollection<T> : IDisposable
    {
        #region Fields
        private readonly Queue<T> m_collection = new Queue<T>();
        private readonly Queue<TaskCompletionSource<T>> waitingQueue = new Queue<TaskCompletionSource<T>>();
        #endregion
    
        public void Add(T item)
        {
            TaskCompletionSource<T> tcs = null;
            lock (m_collection)
            {
                if (waitingQueue.Count > 0)
                {
                    tcs = waitingQueue.Dequeue();
                }
                else
                {
                    m_collection.Enqueue(item);
                }
            }
            if (tcs != null)
            {
                tcs.TrySetResult(item);
            } 
        }

        public Task<T> Take()
        {
            lock (m_collection)
            {
                if (m_collection.Count > 0)
                {
                    return Task.FromResult(m_collection.Dequeue());
                }
                else
                {
                    var tcs = new TaskCompletionSource<T>();
                    waitingQueue.Enqueue(tcs);
                    return tcs.Task;
                }
            }
        }

        public void Dispose()
        {
            
        }
    }
}
